﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Task_When_GetIsCompleted.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Defines the Task_When_GetIsCompleted type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Threading
{
    using System.Threading;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Mocks;
    using Testing.Threading;

    [TestClass]
    public class Task_When_GetIsCompleted
    {
        [TestMethod]
        public void If_Not_Started_Should_Return_False()
        {
            var task = Task.Factory.From(MockDelegates.DoNothing);
            Assert.IsFalse(task.IsComplete);
        }

        [TestMethod]
        public void If_Started_But_Not_Complete_Should_Return_False()
        {
            var resetEvent = new ManualResetEvent(false);

            var task = Task.Factory.From(() => resetEvent.WaitOne());
            try
            {
                task.Start();
                Assert.IsFalse(task.IsComplete);
            }
            finally
            {
                resetEvent.Set();
                task.Wait();
            }
        }

        [TestMethod]
        [HostType("CHESS")]
        public void If_In_Callback_Should_Return_True()
        {
            var result = string.Empty;

            // start task and query IsComplete in callback
            var task = Task.Factory.From(() => MockDelegates.DoNothing);
            task.Start(t => result = task.IsComplete
                ? result = TestStrings.Success
                : TestStrings.Failure);

            // sleep until we have a result
            AsyncUtility.SleepUntil(() => result != string.Empty);

            // verify the result
            Assert.AreEqual(TestStrings.Success, result);
        }

        [TestMethod]
        [HostType("CHESS")]
        public void If_Wait_Signaled_Should_Return_True()
        {
            // start task
            var task = Task.Factory.From(MockDelegates.DoNothingAndReturnSuccess);
            task.Start();

            // wait for task
            task.Wait();

            // verify results
            Assert.IsTrue(task.IsComplete);
            Assert.AreEqual(TestStrings.Success, task.Result);
        }

        [TestMethod]
        [HostType("CHESS")]
        public void If_Polling_And_IsComplete_Becomes_True_Should_Have_Result_Available()
        {
            // start task
            var task = Task.Factory.FromAsync<string>(
                MockDelegates.DoNothingAndReturnSuccess.BeginInvoke,
                MockDelegates.DoNothingAndReturnSuccess.EndInvoke);
            task.Start();

            // poll IsComplete until true
            AsyncUtility.SleepUntil(() => task.IsComplete);

            // verify results
            Assert.AreEqual(TestStrings.Success, task.Result);
        }

        [TestMethod]
        [HostType("CHESS")]
        [TestProperty("ChessMode", "Repro")]
        [TestProperty("ChessBreak", "Assert")]

        #region ChessScheduleString (not human readable)

        [TestProperty("ChessScheduleString",
            @"bpilaiaaaaaaaaaaaeaaonlnahgabmejjgcfcgcpgnmkhlhpekpfeknhoahekbaiiagabdcenijaeabaommbiimnogjcombngjeh
cdcjklckibmkgffggffnggbgeammonjnlmphnohloplnphnohloplnphlkdljneochphnpppdpfmgggeabgmpgmoeknkmjjocbia
kkmibpdphohmbpdpcchomnfpodnhpidfpappfpelhpponplpkgpmdelpppbgnohhlpegohhdndmohmihohpppohpaadlmgieecfb
aaaaaa"
            )]

        #endregion

        public void If_Polling_And_IsComplete_Becomes_True_Should_Have_Error_Available()
        {
            // start task
            var task = Task.Factory.FromAsync(
                MockDelegates.DoNothingAndThrowSuccess.BeginInvoke,
                MockDelegates.DoNothingAndThrowSuccess.EndInvoke);
            task.Start();

            // poll IsComplete until true
            AsyncUtility.SleepUntil(() => task.IsComplete);

            // verify results
            Assert.AreEqual(TestStrings.Success, task.Error.Message);
        }
    }
}
